/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package devbureau.fstore.util;

import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import org.apache.log4j.Logger;

/**This class keeps commonly used methods.
 *
 * @author SSheypak
 */
public class Utilities {

    private static final Logger log = Logger.getLogger(Utilities.class);

    public static class DateTime {

        private static final SimpleDateFormat sdfLong = new SimpleDateFormat("dd.MM.yyyy HH:mm");
        private static final SimpleDateFormat sdfLongHD = new SimpleDateFormat("HH:mm dd.MM.yyyy");
        private static final SimpleDateFormat sdfShort = new SimpleDateFormat("dd.MM.yyyy");

        /**format using pattern dd.MM.yyyy HH:mm*/
        public static String formatLong(Date d) {
            String s = "";
            try {
                s = sdfLong.format(d);
            } catch (Exception e) {
                log.error("Error while formatting date[" + d + "]", e);
            }
            return s;
        }

        public static String formatLongHourDay(Date d){
            String s = "";
            try {
                s = sdfLongHD.format(d);
            } catch (Exception e) {
                log.error("Error while formatting date[" + d + "]", e);
            }
            return s;
        }

        public static Date parseShort(String strDate) {
            Date d = null;
            try {
                d = sdfShort.parse(strDate);
            } catch (Exception e) {
                log.error("Error while parsing date[" + strDate + "]. " + e.getMessage());
            }
            return d;
        }

        /**format using pattern dd.MM.yyyy*/
        public static String formatShort(Date d) {
            String s = "";
            try {
                s = sdfShort.format(d);
            } catch (Exception e) {
                log.error("Error while formatting date[" + d + "]", e);
            }
            return s;
        }

        /**The start of curent day*/
        public static Date getStartDate(Date date) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            cal.set(Calendar.AM_PM, 0);
            cal.set(Calendar.HOUR, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.set(Calendar.SECOND, 0);
            return cal.getTime();
        }

        /**The start of next day*/
        public static Date getEndDate(Date date) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            cal.set(Calendar.HOUR, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.add(Calendar.DAY_OF_YEAR, 1);
            return cal.getTime();
        }

        /**The start of last week*/
        public static Date getLastWeekStart() {
            Calendar cal = Calendar.getInstance();
            cal.add(Calendar.WEEK_OF_YEAR, -1);
            cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            cal.set(Calendar.HOUR, 0);
            cal.set(Calendar.MINUTE, 0);
            return cal.getTime();
        }

        /**The start of last month*/
        public static Date getLastMonthStart() {
            Calendar cal = Calendar.getInstance();
            if (cal.get(Calendar.MONTH) == 0) { //if current month is January
                cal.roll(Calendar.YEAR, false);
            }
            cal.roll(Calendar.MONTH, false);
            cal.set(Calendar.DAY_OF_MONTH, 1);
            cal.set(Calendar.HOUR, 0);
            cal.set(Calendar.MINUTE, 0);
            return cal.getTime();
        }

        public static Date getCurrentMonthStart() {
            return getLastMonthEnd();
        }

        /**The start of current month*/
        public static Date getLastMonthEnd() {
            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.DAY_OF_MONTH, 1);
            cal.set(Calendar.HOUR, 0);
            cal.set(Calendar.MINUTE, 0);
            return cal.getTime();
        }

        /**The start of current week*/
        public static Date getLastWeekEnd() {
            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            cal.set(Calendar.HOUR, 0);
            cal.set(Calendar.MINUTE, 0);
            return cal.getTime();
        }

        public static Date getCurrentWeekStart() {
            return getLastWeekEnd();
        }
    }

    public static class Formatting{
        private static final NumberFormat dfFrance = DecimalFormat.getCurrencyInstance(Locale.FRENCH);

        public static String formatAsCurrency( Number number){
            String s = "";
            try{
                s = dfFrance.format(number);
                s = s.replace(" ¤", "");
            }catch(Exception e){
                log.error("Error while formatting currency. " +e.getMessage());
                s = "";
            }
            return s;
            
        }

        /**@deprecated use formatAsCurrency.*/
        public static String formatPrice(Number num){
            return formatAsCurrency(num);
//            String s = "";
//            if(num!=null){
//                s = dfFrance.format(num);
//            }
//            s = s.replace(" руб.", "");
//            if(!s.contains("\\.") && !s.contains(",")){
//                s+=",00";
//            }
//            return s;
        }

        public static String format(Integer i){
            return i == null? "0" : i.toString();
        }

    public static <T extends Number> T parse(String s, Class<T> clz){
        log.debug("parse ["+s+"]");
        T number = null;
        Method valueOf = null;
        if(s!=null && !s.isEmpty()){
            s = s.trim().replace(" ", "");
            log.debug("parse cleaned string["+s+"]");
        }

        try{
            valueOf = clz.getMethod("valueOf", String.class);
            number = (T)valueOf.invoke(clz, s.replace(",", "."));
        }catch(Exception e){
            log.debug("Can't parse ["+s.replace(",", ".")+"]. Inverting separator token ..");
            try{
                number = (T)valueOf.invoke(clz, s.replace(".", ","));
            }catch(Exception e2){
                log.debug("Can't parse ["+s.replace(".", ",")+"]. Returning null...");
            }
        }
        return number;
    }
    }
}
